package com.hb.trade.server.project.section.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb.core.pojo.enums.SectionStatusEnum;
import com.hb.core.pojo.parent.MPBaseController;
import com.hb.core.pojo.parent.PageResult;
import com.hb.core.pojo.project.calibration.entity.BidWinResultSupply;
import com.hb.core.pojo.project.file.entity.BidFileInfo;
import com.hb.core.pojo.project.homepage.dto.StatisticUserParam;
import com.hb.core.pojo.project.homepage.vo.BidSectionStatisticVO;
import com.hb.core.pojo.project.notice.entity.Notice;
import com.hb.core.pojo.project.proj.dto.BidProjectDTO;
import com.hb.core.pojo.project.proj.entity.AbstractProject;
import com.hb.core.pojo.project.proj.enums.BidWayEnum;
import com.hb.core.pojo.project.section.dto.BidSectionCountDTO;
import com.hb.core.pojo.project.section.dto.BidSectionDTO;
import com.hb.core.pojo.project.section.entity.BidSection;
import com.hb.trade.server.project.calibration.service.BidWinResultSupplyService;
import com.hb.trade.server.project.file.manager.BidFileInfoManager;
import com.hb.trade.server.project.file.service.BidFileInfoService;
import com.hb.trade.server.project.notice.service.NoticeService;
import com.hb.trade.server.project.proj.service.ProjectService;
import com.hb.trade.server.project.section.manager.BidSectionManager;
import com.hb.trade.server.project.section.service.item.ConsoleItemServiceUtil;
import com.hb.trade.server.project.section.service.raw.BidSectionService;
import org.apache.commons.collections4.CollectionUtils;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.msg.ResponseDto;
import org.fzzn.core.util.MsgUtil;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 采购方案/标段(包)信息表 前端控制器
 *
 * @author zhaojk
 * @since 2021-08-30
 */
@RestController
public class BidSectionController extends MPBaseController<BidSection, BidSectionService> {

    protected final BidFileInfoService bidFileInfoService;
    protected final BidWinResultSupplyService bidWinResultSupplyService;
    protected final NoticeService noticeService;
    protected final ProjectService projectService;

    public BidSectionController(BidSectionService service,
                                BidWinResultSupplyService bidWinResultSupplyService,
                                NoticeService noticeService,
                                BidFileInfoService bidFileInfoService,
                                ProjectService projectService) {
        super(service);
        this.bidFileInfoService = bidFileInfoService;
        this.bidWinResultSupplyService = bidWinResultSupplyService;
        this.noticeService = noticeService;
        this.projectService = projectService;
    }


    /**
     * @param bidSection:
     * @Description: 根据项目查询已经发布过公告(除控制价公告)的的标段列表
     * @Author: zhongdl
     * @Date:2021/12/24 15:05
     * @return: {@link Message< BidSectionDTO> }
     **/
    @PostMapping("/bidSection/listReleaseNotice")
    public Message<List<BidSection>> listReleaseNotice(@RequestBody BidSectionDTO bidSection) {
        List<BidSection> bidSectionList = service.listReleaseNotice(bidSection.getProjectId());
        // 控制价公告不需要修改标段状态
//        BidSection byId = service.getById(bidSection.getId());
//        BidSectionManager to = byId.to(BidSectionManager.class);
//        to.refreshBidSection();
        return MsgUtil.success(bidSectionList);
    }

    /**
     * @param bidSection:
     * @Description: 根据标段id查询项目信息和标段信息
     * @Author: zhongdl
     * @Date:2021/12/24 15:05
     * @return: {@link Message< BidSectionDTO> }
     **/
    @PostMapping("/bidSection/getBidSectionProjectInfo")
    public Message<BidSectionDTO> getBidSectionProjectInfo(@RequestBody BidSectionDTO bidSection) {
        BidSectionDTO bidSectionDTO = service.findBidAndProjectBySectionId(bidSection.getSectionId());
        //
        if(bidSectionDTO == null){
            return MsgUtil.success(bidSectionDTO);
        }
        //查询公告信息
        Notice notice = noticeService.lastNoticeBySectionId(bidSectionDTO.getId());
        bidSectionDTO.setNoticeTitle(notice == null ? null : notice.getNoticeTitle());
        return MsgUtil.success(bidSectionDTO);
    }

    /**
     * 根据项目id和已选择的标段id  查询未选择的标段id
     *
     * @param sectionList 已选择的标段id
     * @param projectId   项目id
     * @return
     */
    @PostMapping("/bidSection/findNotChoiceBidSectionList")
    public Message<List<BidSection>> findNotChoiceBidSectionList(@RequestBody List<String> sectionList, @RequestParam(value = "projectId") Long projectId) {
        QueryWrapper<BidSection> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "section_code", "section_name", "section_status");
        queryWrapper.lambda().eq(BidSection::getProjectId, projectId);
        List<BidSection> bidSectionList = service.list(queryWrapper);
        if (CollectionUtils.isNotEmpty(sectionList) && CollectionUtils.isNotEmpty(bidSectionList)) {
            bidSectionList = bidSectionList.stream().filter(bidSection -> !CollectionUtils.containsAny(sectionList, bidSection.getId())).collect(Collectors.toList());
        }
        return MsgUtil.success(bidSectionList);
    }

    /**
     * 设置指定标段的监标人
     *
     * @param bidSection
     * @return
     */
    @PostMapping("/bidSection/update/monitorName")
    public Message<Boolean> updateMonitorName(@RequestBody BidSectionDTO bidSection) {
        Long sectionId = bidSection.getId();
        if (sectionId == null) {
            return MsgUtil.fail("标段ID不能为空");
        }
        BidSection section = service.getById(sectionId);

        String monitorName = bidSection.getMonitorName();
        if (monitorName == null) {
            monitorName = "";
        }
        section.setMonitorName(monitorName);
        boolean update = service.updateById(section);
        return MsgUtil.msg(update);
    }

    /**
     * 根据标段Id查询标段信息
     *
     * @param bidSectionDTO
     * @return
     */
    @PostMapping("/bidSection/info")
    public Message<BidSection> info(@RequestBody BidSectionDTO bidSectionDTO) {
        if (null == bidSectionDTO || null == bidSectionDTO.getSectionId()) {
            return MsgUtil.fail("参数为空");
        }
        BidSection section = service.getOne(new LambdaQueryWrapper<BidSection>()
                .eq(BidSection::getId, bidSectionDTO.getSectionId()));
        if (section == null) {
            return MsgUtil.fail("无数据");
        }
        return MsgUtil.success(section);
    }

    @PostMapping("/bidSection/getBidSection")
    public Message<BidSectionDTO> getBidSection(@RequestBody BidSectionDTO bidSectionDTO){
        BidSection section = service.getOne(new LambdaQueryWrapper<BidSection>()
                .eq(BidSection::getId, bidSectionDTO.getSectionId()));
        if (section == null) {
            return MsgUtil.fail("无数据");
        }
        bidSectionDTO = section.to(BidSectionDTO.class);
        AbstractProject abstractProject = projectService.getById(section.getProjectId());
        bidSectionDTO.setProjectCode(abstractProject.getProjectCode());
        bidSectionDTO.setProjectName(abstractProject.getProjectName());
        return MsgUtil.success(bidSectionDTO);

    }

    /**
     * 开标
     *
     * @param sectionId
     * @return
     */
    @GetMapping("/bidSection/open")
    public Message<Boolean> open(@RequestParam(value = "sectionId") Long sectionId) {
        BidSection section = service.getById(sectionId);
        if (section == null) {
            return MsgUtil.fail("无数据");
        }
        // FIXME 标段开标逻辑
        // 标段状态, 开标中
        section.setSectionStatus(SectionStatusEnum.BID_OPENING.getId());
        boolean update = service.updateById(section);
        return MsgUtil.msg(update);
    }

    /**
     * 根据标段Id查询所有标段信息
     *
     * @param sectionId
     * @return
     */
    @GetMapping("/bidSection/findBidSectionsBySectionId")
    public Message<List<BidSection>> findBidSectionsBySectionId(@RequestParam(value = "sectionId") Long sectionId) {
        List<BidSection> sectionList = service.listSections(sectionId);
        return MsgUtil.success(sectionList);
    }

    /**
     * 更改标段状态
     *
     * @return
     */
    @PostMapping("/bidSection/launchSection")
    public Message launchSection(@RequestBody BidSectionDTO bidSection) {
        Long sectionId = bidSection.getId();
        if (sectionId == null) {
            return MsgUtil.fail("缺少必要参数");
        }
        BidSection section = service.getById(sectionId);
        if (section == null) {
            return MsgUtil.fail("没有数据");
        }

        BidSectionManager sectionManager = section.to(BidSectionManager.class);
        SectionStatusEnum sectionStatusEnum = sectionManager.getSectionStatusEnum();

        // 只更改标段状态为已保存的数据
        if (SectionStatusEnum.PROJECT_SAVED == sectionStatusEnum) {
            // FIXME这里还应该有一个验证逻辑, 需要通过工作流验证该项目是否已经通过审核
            // ...
            section.setSectionStatus(SectionStatusEnum.PROJECT_SAVED.getId());
            section.buildBaseData(2);
            boolean updateById = service.updateById(section);
            return MsgUtil.msg(updateById);
        }
        return MsgUtil.fail("没有数据");
    }

    @PostMapping("/bidSection/findBidSectionList")
    public Message<?> findBidSectionList(@RequestBody BidSectionDTO bidSection) {
        Object obj = service.findBidSectionList(bidSection);
        return MsgUtil.success(obj);
    }

    /**
     * 查询指定项目下的标段列表
     *
     * @param bidSection#projectId
     * @return
     * @author zhaojk
     */
    @PostMapping("/bidSection/listBidSectionsByProjectId")
    public Message<?> listBidSectionsByProjectId(@RequestBody BidSectionDTO bidSection) {
        Object obj = service.findBidSectionList(bidSection);
        return MsgUtil.success(obj);
    }

    /**
     * @param bidSection:
     * @Description: 投标人查询项目大厅列表
     * @Author: zhongdl
     * @Date:2021/12/31 16:17
     * @return: {@link Message<  PageResult < BidSectionDTO>> }
     **/
    @PostMapping("/bidSection/pageProjectHall")
    public Message<PageResult<BidSectionDTO>> pageProjectHall(@RequestBody BidSectionDTO bidSection) {
        PageResult<BidSectionDTO> pageProjectHall = service.pageProjectHall(bidSection);
        return MsgUtil.success(pageProjectHall);
    }

    /**
     * @param bidSection:
     * @Description:投标人我的项目 (1):需要报名的项目 报名成功 到 我的项目
     * (2 ):不需要报名的项目需要购买文件  购买完文件 到我的项目
     * (3 ): 不需要报名的项目不要购买文件 下载完文件 到 我的项目
     * @Author: zhongdl
     * @Date:2022/1/4 8:59
     * @return: {@link Message< PageResult< BidSectionDTO>> }
     **/
    @PostMapping("/bidSection/pageMyProject")
    public Message<PageResult<BidSectionDTO>> pageMyProject(@RequestBody BidSectionDTO bidSection) {
        PageResult<BidSectionDTO> pageMyProject = service.pageMyProject(bidSection, 2);
        return MsgUtil.success(pageMyProject);
    }



    /* ************************ 控制台按钮 start ************************ */

    /**
     * 所有控制台按钮, 不过滤, 前端调试用
     *
     * @return
     */
    @PostMapping("/console/items/all")
    public Message<List<JSONObject>> itemsAll() {
        List<JSONObject> items = service.listConsoleItems(null, null, null);
        for (JSONObject item : items) {
            ConsoleItemServiceUtil.logic(item, null);
        }
        return MsgUtil.success(items);
    }


    /**
     * 获取指定标段的控制台按钮
     *
     * @param consoleItemDto
     * @return
     */
    @PostMapping("/console/items/sectionId")
    public Message<List<JSONObject>> itemsSectionId(@RequestBody JSONObject consoleItemDto) {
        Integer roleSign = consoleItemDto.getInt("roleSign");
        if (roleSign == null) {
            return MsgUtil.fail("roleSign 参数不能为空");
        }
        Long sectionId = consoleItemDto.getLong("sectionId");
        if (sectionId == null) {
            return MsgUtil.fail("sectionId 参数不能为空");
        }

        BidSection section = service.getById(sectionId);

        // 获取当前标段的招标方式
        Integer bidWay = consoleItemDto.getInt("bidWay");
        if (bidWay == null) {
            BidSectionManager sectionManager = section.to(BidSectionManager.class);
            BidWayEnum anEnum = sectionManager.getBidWayEnum();
            bidWay = anEnum.getCode();
        }

        // 获取当前标段的状态
        Long statusId = consoleItemDto.getLong("statusId");
        if (statusId == null) {
            statusId = section.getSectionStatus();
        }

        // 查询符合条件的控制台按钮
        List<JSONObject> items = service.listConsoleItems(statusId, roleSign, bidWay);

        // 更新按钮状态
        for (JSONObject item : items) {
            ConsoleItemServiceUtil.logic(item, section.to(BidSectionDTO.class));
        }
        CollUtil.filter(items, (elem) -> elem.getInt("showStatus") != null && elem.getInt("showStatus") != 0);

        return MsgUtil.success(items);
    }
    /* ************************ 控制台按钮  end ************************ */

    @PostMapping("/bidSection/findBidSectionsByNoticeId")
    public Message<List<BidSectionDTO>> findBidSectionsByNoticeId(Long noticeId) {
        List<BidSectionDTO> sections = service.findBidSectionsByNoticeId(noticeId);
        return MsgUtil.success(sections);
    }

    /**
     * 查询首次公告未发布过的标段信息
     *
     * @param sectionDTO projectId参数必传
     * @return
     */
    @PostMapping("/bidSection/noFirstNotice/sections")
    public Message<List<BidSection>> noFirstSections(@RequestBody BidSectionDTO sectionDTO) {
        Long projectId = sectionDTO.getProjectId();
        if (projectId == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        BidSectionDTO bidSection = new BidSectionDTO();

        bidSection.setProjectId(projectId);

        bidSection.setQueryValue(projectId);
        bidSection.setQueryType(1); // 查询未发布过首次公告的标段

        List<BidSection> bidSectionArr = service.findBidSectionArr(bidSection);
        return MsgUtil.success(bidSectionArr);
    }

    /**
     * 查询首次公告未发布过的标段信息
     *
     * @param sectionDTO projectId参数必传
     * @return
     */
    @PostMapping("/bidSection/noBidFile/sections")
    public Message<List<BidSection>> noBidFileSections(@RequestBody BidSectionDTO sectionDTO) {
        Long projectId = sectionDTO.getProjectId();
        if (projectId == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        BidSectionDTO bidSection = new BidSectionDTO();

        bidSection.setProjectId(projectId);

        bidSection.setQueryType(2); // 查询未发布招标文件的标段

        List<BidSection> bidSectionArr = service.findBidSectionArr(bidSection);
        return MsgUtil.success(bidSectionArr);
    }

    /**
     * @param bidSectionDTO:
     * @Description: 标段管理列表关联招标文件
     * @Author: zhongdl
     * @Date:2022/1/10 13:20
     * @return: {@link Message< Boolean> }
     **/
    @PostMapping("/bidSection/relateBidFile")
    public Message<Boolean> relateBidFile(@RequestBody BidSectionDTO bidSectionDTO) {
        BidSection bidSection = service.getById(bidSectionDTO.getId());
        if (bidSection.getFileId() != null) {
            return MsgUtil.fail("该标段已经关联招标文件,不能重复关联");
        }
        //查询招标文件设置标段属性
        BidFileInfo bidFileInfo = bidFileInfoService.getById(bidSectionDTO.getFileId());
        bidFileInfo.to(BidFileInfoManager.class).getSectionOptions().to(bidSectionDTO);
        service.updateById(bidSectionDTO);
        return MsgUtil.msg(true);
    }

    /**
     * 根据企业ID（必填)查询所有的项目和对应的标段信息
     * 投标人投诉选择标段使用
     *
     * @param bidProjectDTO
     * @return
     * @Author: ljs
     * @Date:2022-2-8 10:30:54
     */
    @PostMapping("/bidSection/listMySection")
    public Message<List<AbstractProject>> listMySection(@RequestBody BidProjectDTO bidProjectDTO) {
        if (bidProjectDTO == null || bidProjectDTO.getOrgId() == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        List<AbstractProject> projectList = service.listMySection(bidProjectDTO);
        return MsgUtil.success(projectList);
    }

    /**
     *根据企业ID查询未递交投标文件的标段
     * @param bidSectionDTO
     * @return
     * @Author: ljs
     * @Date:2022-2-18 18:17:52
     */
    @PostMapping("/bidSection/notSubmitSectionList")
    public Message notSubmitSectionList(@RequestBody BidSectionDTO bidSectionDTO){
        if (bidSectionDTO == null || bidSectionDTO.getCreateId() == null){
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        Page<BidSectionDTO> bidSectionDTOPage = service.pageNotSubmitSection(bidSectionDTO);
        return MsgUtil.success(PageResult.get(bidSectionDTOPage));
    }

    /**
     *
     * @Description: 查询参与该标段的项目
     * @Author: zhongdl
     * @Date:2022/2/18 18:06
     * @param id:
     * @return: {@link Message< List< Long>> }
     **/
    @PostMapping("/bidSection/listParticipateSection")
    public Message<List<Long>> listParticipateSection(@RequestParam Long id){
         List<Long> ids = service.listParticipateSection(id);
         return MsgUtil.success(ids);
    }

    /**
     * 根据月份查询 具有开标安排的日期
     * @param bidSectionDTO
     * @return
     */
    @PostMapping("/bidSection/openDateList")
    public Message<List<BidSectionDTO>> openDateList(@RequestBody BidSectionDTO bidSectionDTO){
        List<BidSectionDTO> bidSectionDTOList = service.openDateList(bidSectionDTO);
        return MsgUtil.success(bidSectionDTOList);
    }


    /**
     *
     * @Description:根据开标时间查询标段列表
     * @Author: zhongdl
     * @Date:2022/2/19 11:08
     * @param bidSectionDTO:
     * @return: {@link Message< List< BidSectionDTO>> }
     **/
    @PostMapping("/bidSection/listBidSectionByOpenBidTime")
    public Message<List<BidSectionDTO>> listBidSectionByOpenBidTime(@RequestBody BidSectionDTO bidSectionDTO){
          List<BidSectionDTO> bidSectionDTOS = service.listBidSectionByOpenBidTime(bidSectionDTO);
          return MsgUtil.success(bidSectionDTOS);
    }

    /**
     *
     * @Description:门户网站查询 完成项目金额总数、项目数等
     * @Author: ljs
     * @Date:2022-2-19 16:07:44
     * @param bidSectionCountDTO:
     *
     **/
    @PostMapping("/bidSection/bidSectionCount")
    public Message<BidSectionCountDTO> bidSectionCount(@RequestBody BidSectionCountDTO bidSectionCountDTO){
        // 查询标段数
        Long bidSectionCount = service.count();
        // 查询已发布中标公告标段数
        QueryWrapper<BidWinResultSupply> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("count(DISTINCT section_id) as bidWinCount", "sum(successful_amount) as successfulAmountCount");
//        Long bidWinCount = bidWinResultSupplyService.count(queryWrapper);
        BidWinResultSupply bidWinResultSupply = bidWinResultSupplyService.getOne(queryWrapper);
        Long bidWinCount = bidWinResultSupply.getBidWinCount();
        // 总中标金额
        Long successfulAmountCount = bidWinResultSupply.getSuccessfulAmountCount();
        if (successfulAmountCount == null){
            successfulAmountCount = 0L;
        }
        // 查询截止公告标段数
        QueryWrapper<Notice> noticeQueryWrapper = new QueryWrapper<>();
        noticeQueryWrapper.select("DISTINCT project_id");
        noticeQueryWrapper.eq("notice_nature", 5);
        Long endingCount = noticeService.count(noticeQueryWrapper);
        // 已完成项目数
        Long completeSectionCount = bidWinCount + endingCount;
        // 进行中项目数
        Long ongoingSectionCount = bidSectionCount - completeSectionCount;
        // 给对象赋值
        BidSectionCountDTO sectionCountDTO = new BidSectionCountDTO();
        sectionCountDTO.setBidSectionCount(bidSectionCount);
        sectionCountDTO.setOngoingSectionCount(ongoingSectionCount);
        sectionCountDTO.setSuccessfulAmountCount(successfulAmountCount);
        sectionCountDTO.setCompleteSectionCount(completeSectionCount);
        return MsgUtil.success(sectionCountDTO);
    }

    /**
     * 首页的项目数量统计
     * @param statisticUserParam
     * @return
     */
    @PostMapping("/bidSection/homepageSectionStatistic")
    public Message<BidSectionStatisticVO> homepageSectionStatistic(@RequestBody StatisticUserParam statisticUserParam){
        BidSectionStatisticVO bidSectionStatisticVO = service.homepageSectionStatistic(statisticUserParam);
        return MsgUtil.success(bidSectionStatisticVO);
    }

    /**
     * 根据项目id 查询标段
     *
     * @param bidSectionDTO
     * @return
     */
    @PostMapping("/bidSection/listByProjectId")
    public Message<PageResult<BidSectionDTO>> getSectionByProjectId(@RequestBody BidSectionDTO bidSectionDTO) {
        Page<BidSectionDTO> list = this.service.selectListByProjectId(bidSectionDTO);
        return MsgUtil.success(PageResult.get(list));
    }

    /**
     * 根据项目id 查询所有通过报名的企业(门户使用)
     *
     * @param projectId
     * @return
     * author：lsj
     */
    @PostMapping("/bidSection/getTenderOrgByProjectId")
    public List<String> getTenderOrgByProjectId(@RequestBody String projectId){
        List<String> OrgNameList = this.service.getTenderOrgByProjectId(projectId);
        return OrgNameList;
    }


    /**
     * 根据项目id 查询标段
     *
     * @param bidSectionDTO
     * @return
     */
    @PostMapping("/bidSection/listSubmitInfoByProjectId")
    public Message<PageResult<BidSectionDTO>> listSubmitInfoByProjectId(@RequestBody BidSectionDTO bidSectionDTO) {
        Page<BidSectionDTO> list = this.service.listSubmitInfoByProjectId(bidSectionDTO);
        return MsgUtil.success(PageResult.get(list));
    }

    /**
     * 根据招标文件查询关联的标段
     *
     * @author yuezheng
     * @param fileId
     * @return List<BidSectionDTO>
     * @date 2022/4/21 5:48 PM
     */
    @PostMapping("/bidSection/listByFileId")
    public Message<List<BidSection>> listByFileId(@RequestBody Long fileId) {
        List<BidSection> bidSections = this.service.selectSectionByBidFileId(fileId);
        return MsgUtil.success(bidSections);
    }

    /**
     * @Description: 邀请书编辑专用标段列表
     *
     * @author yuezheng
     * @param bidSectionDTO
     * @return org.fzzn.core.model.msg.Message<java.util.List>
     * @date 2022/5/25 17:13
     */
    @PostMapping("/bidSection/inviteSectionList")
    public Message<List> inviteSectionList(@RequestBody BidSectionDTO bidSectionDTO) {
        List bidSectionList = service.getBidSectionList(bidSectionDTO);
        return MsgUtil.msg(bidSectionList);
    }
}
